package net.wantongtech.xa.uploadbasicinfo.config;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.wtkj.vo.dzzf.base.qxsjz.entity.basic.TollProvince;
import lombok.Getter;
import lombok.Setter;
import net.wantongtech.xa.uploadbasicinfo.dao.LoadTollBasicInfoDao;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 清分结算收费公路基础信息配置
 *
 * @author MaShibo
 * 日期 :  2019/11/29
 */
public class TollBasicInfoConfig {


    @Getter
    @Setter
    private String sysChangeDate;

    /**
     * key : tollProvinceId
     * value : 清分方/发行方信息
     */
    private Map<String, TollProvince> tollProvinceIdMap;

    /**
     * key : 收费站编号
     * value : 收费站名称
     */
    private Map<String, String> stationMap;


    /**
     * key : 6107发行方号段
     * value : 银行自发渠道编号
     */
    private Map<String, String> sectionNo2ChannelTypeMap;


    /**
     * key : 发行方编码，6位
     * value : 银行自发渠道编号
     */
    private Map<String, String> issuerId2ChannelTypeMap;


    /**
     * keY ：卡片网络编号
     * value : 银行自发渠道编号
     */
    private Map<String, String> netId2ChannelTypeMap;


    /**
     * key ： 渠道编号
     * value : 子发行方编码
     */
    private Map<String, String> channelType2SubIssuerId;

    /**
     * 所有发行方编码
     */
    private static Set<String> allIssuerIds;


    static {
        ImmutableSet.Builder<String> builder = new ImmutableSet.Builder<>();
        builder.add("610101");
        builder.add("610102");
        builder.add("610103");
        builder.add("610105");
        builder.add("610106");
        builder.add("610107");
        allIssuerIds = builder.build();
    }


    @Resource
    private LoadTollBasicInfoDao loadTollBasicInfoDao;


    @PostConstruct
    public void init() {
        tollProvinceIdMap = loadTollBasicInfoDao.queryTollProvinceIdMap();
        if (tollProvinceIdMap.isEmpty()) {
            throw new IllegalStateException("未查询到请分方/服务方编码信息");
        }
        stationMap = loadTollBasicInfoDao.queryStationMap();
        if (stationMap.isEmpty()) {
            throw new IllegalStateException("未查询到收费站基础信息");
        }
        sectionNo2ChannelTypeMap = loadTollBasicInfoDao.querySectionNo2ChannelTypeMap();
        if (sectionNo2ChannelTypeMap.isEmpty()) {
            throw new IllegalStateException("未查询到6107号段与银行自发渠道编号的映射信息");
        }
        issuerId2ChannelTypeMap = loadTollBasicInfoDao.queryIssuerId2ChannelTypeMap();
        if (issuerId2ChannelTypeMap.isEmpty()) {
            throw new IllegalStateException("未查询到非6102 - 6106发行方编号与银行自发渠道编号的映射信息");
        }
        channelType2SubIssuerId = loadTollBasicInfoDao.queryChannelType2SubIssuerIdMap();
        if (channelType2SubIssuerId.isEmpty()) {
            throw new IllegalStateException("未查询到6107渠道编码与子发行方编码的映射信息");
        }

        //构造卡片网络编号与渠道编码的映射关系
        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
        issuerId2ChannelTypeMap.forEach((issuerId, channelType) ->
                builder.put(issuerId.replaceFirst("01", ""), channelType));
        netId2ChannelTypeMap = builder.build();
    }


    /**
     * 每天凌晨1点合并变更
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void merge() {
        Map<String, String> tempMap = loadTollBasicInfoDao.queryStationMap();
        tempMap.forEach((id, name) -> {
            if (!stationMap.containsKey(id)) {
                stationMap.put(id, name);
            }
        });
    }


    /**
     * 根据请分方/服务方ID获取对应信息
     *
     * @param tollProvinceId 请分方/服务方ID
     * @return 对应信息
     */
    public TollProvince getTollProvinceById(String tollProvinceId) {
        return tollProvinceIdMap.get(tollProvinceId);
    }


    /**
     * 根据收费站编码获取对应名称
     *
     * @param stationId 收费站编码
     * @return 收费站名称
     */
    public String getStationName(String stationId) {
        return stationMap.get(stationId);
    }


    /**
     * 根据6107独特的号段获取对应的银行自发渠道编号
     *
     * @param sectionNo 号段
     * @return 对应银行自发渠道编号
     */
    public String getChannelTypeBySectionNo(String sectionNo) {
        Validate.isTrue(StringUtils.length(sectionNo) == 2);
        return sectionNo2ChannelTypeMap.get(sectionNo);
    }


    /**
     * 根据发行方ID（6102 - 6106）获取对应的银行自发渠道编号
     *
     * @param issuerId 发行方编号
     * @return 对应银行自发渠道编号
     */
    public String getChannelTypeByIssuerId(String issuerId) {
        Validate.isTrue(StringUtils.length(issuerId) == 6);
        return issuerId2ChannelTypeMap.get(issuerId);
    }


    /**
     * 根据卡片网络编号（6102 - 6106）获取对应的银行自发渠道编号
     *
     * @param cardNetId 卡片网络编号
     * @return 对应银行自发渠道编号
     */
    public String getChannelTypeByCardNetId(String cardNetId) {
        Validate.isTrue(StringUtils.length(cardNetId) == 4);
        return netId2ChannelTypeMap.get(cardNetId);
    }

    /**
     * 根据银行自发渠道编号 获取发行方ID
     *
     * @param channelType 对应银行自发渠道编号
     * @return 新发行方编号
     */
    public String getIssuerIdByChannelType(String channelType) {
        for (Map.Entry<String, String> entry : issuerId2ChannelTypeMap.entrySet()) {
            if (channelType.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return null;
    }


    /**
     * 根据子发行方编号获取对应渠道编号
     *
     * @param subIssuerId 子发行方编号
     * @return 渠道编号
     */
    public String getChannelTypeBySubIssuerId(String subIssuerId) {
        for (Map.Entry<String, String> entry : channelType2SubIssuerId.entrySet()) {
            String channelType = entry.getKey();
            String tempSubIssuerId = entry.getValue();
            if (StringUtils.endsWith(subIssuerId, tempSubIssuerId)) {
                return channelType;
            }
        }
        return null;
    }

    /**
     * 获取子发行发编码（旧编码）
     *
     * @return 子发行方编码集合
     */
    public Set<String> subIssuerIdSet() {
        return channelType2SubIssuerId.entrySet().stream()
                .map(Map.Entry::getValue)
                .collect(Collectors.toSet());
    }


    /**
     * 获取所有发行方编码（短）
     *
     * @return 发行方编码集合
     */
    public Set<String> allIssuerIds() {
        return allIssuerIds;
    }

    /**
     * 获取服务方信息Map
     *
     * @return 服务方Map
     */
    public Map<String, TollProvince> tollProvinceMap() {
        return tollProvinceIdMap;
    }

}
